<?php

namespace App\Http\Logic;

use App\Models\SwtIdentity;
use App\Models\SwtTradeAddress;
use App\Models\SwtTransferOrder;
use App\Models\SwtTransferOrderBuyer;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use TheSeer\Tokenizer\Exception;

class TransferLogic extends BaseLogic
{
    public static function getViewData(int $user_id) : array|bool
    {
        $res = SwtTradeAddress::whereHas('trade_account', function ($query) {
            $query->where('type', '1');
        })
        -> where('user_id', $user_id)
        -> first();

        if(!$res) {
            self::$error = "账户不存在";
            return false;
        }

        $balance = round($res->total, 2);

        $identity = SwtIdentity::where('user_id', $user_id) -> where('type', 0) ->first();

        if(!$identity) {
            self::$error = "身份不存在";
            return false;
        }

//        $identity -> alipay_code = $identity -> alipay_code ? config('app.url').$identity -> alipay_code : '';
//
//        $identity -> wechat_code = $identity -> wechat_code ? config('app.url').$identity -> wechat_code : '';

        $identity -> balance = $balance;

        $identity -> rate = config('services.shop_admin.transfer_fee') * 100;

        return $identity -> toArray();
    }

    public static function createOrder(int $user_id, int $pay_type, string $num) : string|bool
    {
        $identity = SwtIdentity::where('user_id', $user_id) -> where('type', 0) ->first();

        if(!$identity) {
            self::$error = "身份不存在";
            return false;
        }

        $trade_info = SwtTradeAddress::whereHas('trade_account', function ($query) {
            $query->where('type', '1');
        })
            -> where('user_id', $user_id)
            -> first();

        if(!$trade_info) {
            self::$error = "账户不存在";
            return false;
        }

        $fee = $num * config('services.shop_admin.transfer_fee');

        $real_total = (float) $num + $fee;

        if($real_total > $trade_info -> total) {
            self::$error = "剩余数量不足";
            return false;
        }

        if($pay_type == 0) {
            $pay_data = [
                'name' => $identity->wechat_name,
                'no'   => $identity->wechat_no,
                'code' => $identity->wechat_code,
            ];
        } else {

            $pay_data = [
                'name' => $identity->alipay_name,
                'no'   => $identity->alipay_no,
                'code' => $identity->alipay_code,
            ];
        }

        if(!$pay_data['name']) {
            self::$error = "支付信息不存在";
            return false;
        }

        DB::beginTransaction();

        try {

            $data = [
                'order_sn'  => date('YmdHis').rand(100,999),
                'seller_id' => $user_id,
                'num'       => $num,
                'price'     => 1,
                'total'     => $num,
                'real_total'=> $real_total,
                'fee'       => $fee,
                'pay_type'  => $pay_type,
                'pay_name'  => $pay_data['name'],
                'pay_no'    => $pay_data['no'],
                'pay_code'  => $pay_data['code'],
            ];

            $res = SwtTransferOrder::create($data);

            if(!$res) {
                throw new Exception('新增订单失败');
            }

            $trade_info -> total      -= $real_total;
            $trade_info -> lock_total += $real_total;

            $trade_info -> save();

            DB::commit();

            return $res -> id;

        } catch(\Exception $e) {
            DB::rollBack();
            self::$error = $e -> getMessage();
            return false;
        }
    }

    public static function cancelOrder(int $id, string|null $cancel_desc) : bool
    {
        $order_info = SwtTransferOrder::find($id);

        if($order_info && $order_info -> status != 0) {
            self::$error = "订单当前状态无法取消";
            return false;
        }

        $trade_info = SwtTradeAddress::whereHas('trade_account', function ($query) {
            $query->where('type', '1');
        })
            -> where('user_id', $order_info['seller_id'])
            -> first();

        if(!$trade_info) {
            self::$error = "账户不存在";
            return false;
        }

        DB::beginTransaction();

        try {
            $order_info -> status = 3;
            $order_info -> cancel_desc = $cancel_desc;
            $order_info -> save();

            $trade_info -> total      += $order_info -> real_total;
            $trade_info -> lock_total -= $order_info -> real_total;
            $trade_info -> save();

            DB::commit();
            return true;
        } catch(\Exception $e) {
            DB::rollBack();
            self::$error = $e -> getMessage();
            return false;
        }
    }

    public static function orderList(string $pay_type = "", int $pageSize = 15, int $pageNo = 1) : array
    {
        $where = [
            ['status','=',0],
            ['sign_status','=',1],
        ];

        if($pay_type !== "") {
            $where[] = ['pay_type', '=', $pay_type];
        }

        $orders = SwtTransferOrder::with('seller') -> where($where) -> orderBy('id','desc');

        $pages = $orders -> paginate(
            perPage: $pageSize,
            columns: ['*'],
            pageName: 'pageNo',
            page: $pageNo
        );

        $list = $orders -> get();

        foreach($list as &$v) {
            $user_info = User::find($v ->seller_id) -> toArray();

            $user_info['avatar'] = config('app.url') . '/storage/uploads/avatar/default.png';

            $v['user'] = $user_info;
        }

        return [
            'list'        => $list,
            'pageNo'      => $pages->currentPage(),
            'pageSize'    => $pages->perPage(),
            'count'       => $pages->total(),
            'noMore'      => !$pages->hasMorePages(),
        ];
    }

    public static function orderInfo(int $id) : array
    {
        $order = SwtTransferOrder::with('seller') -> find($id) -> toArray();

        $user_info = User::find($order['seller_id']) -> toArray();

        $user_info['avatar'] = config('app.url') . '/storage/uploads/avatar/default.png';

        $order['user'] = $user_info;

        $order['buyer'] = [];

        if($order['buyer_order_id']) {
            $buyer_order = SwtTransferOrderBuyer::with('buyer') -> find($order['buyer_order_id']) -> toArray();
            $order['buyer'] = $buyer_order['buyer'];
        }

        return $order;
    }

    public static function buyerOrderInfo(int $id) : array
    {
        $order = SwtTransferOrderBuyer::with('order') -> find($id) -> toArray();

        $user_info = User::find($order['order']['seller_id']) -> toArray();

        $user_info['avatar'] = config('app.url') . '/storage/uploads/avatar/default.png';

        $order['user'] = $user_info;

        $order['identity'] = SwtIdentity::where('user_id', $order['order']['seller_id']) -> first() -> toArray();

        return $order;
    }

    public static function lockOrder(int $id, int $user_id) : bool|array
    {
        $info = SwtIdentity::where('user_id', $user_id) -> first();

        if($info -> type == 0) {
            self::$error = "无法购买";
            return false;
        }

        $order = SwtTransferOrder::find($id);

        if($order -> sign_status !== 1 || $order -> status !== 0) {
            self::$error = "当前订单状态无法购买";
            return false;
        }

        DB::beginTransaction();

        try{
            $res = SwtTransferOrderBuyer::create(
                [
                    'order_id'   => $id,
                    'order_sn'   => date('YmdHis') . rand(100, 999),
                    'buyer_id'   => $user_id,
                    'pay_status' => 0,
                    'lock_at'    => date('Y-m-d H:i:s', time())
                ]
            );

            if(!$res) {
                throw new Exception('购买订单下单失败');
            }

            $buyer_order_id = $res -> id;

            $order -> status = 1;

            $order -> buyer_order_id = $buyer_order_id;

            $res = $order -> save();

            if(!$res) {
                throw new Exception('锁定订单失败');
            }

            DB::commit();

            return ['buyer_order_id' =>  $buyer_order_id];

        } catch (Exception $e)
        {
            DB::rollBack();
            self::$error = $e -> getMessage();
            return false;
        }
    }

    public static function payOrder(int $buyer_order_id, int $user_id) : bool
    {
        $order = SwtTransferOrderBuyer::find($buyer_order_id);

        if($order -> buyer_id != $user_id) {
            self::$error = "订单不存在";
            return false;
        }

        $seller_order = SwtTransferOrder::find($order -> order_id);

        if($seller_order -> status != 1) {
            self::$error = "订单支付失败";
            return false;
        }

        $info = SwtIdentity::where('user_id', $user_id) -> first();

        if($info -> type == 0) {
            self::$error = "无法购买";
            return false;
        }

        DB::beginTransaction();
        try {
            $order -> pay_status = 1;

            $order -> lock_at = date('Y-m-d H:i:s', time());

            $res = $order -> save();

            if(!$res) {
                throw new Exception("支付订单失败");
            }

            $seller_order -> status = 2;

            $res = $seller_order -> save();

            if(!$res) {
                throw new Exception("支付订单失败");
            }

            DB::commit();
            return true;
        } catch (Exception $e) {
            DB::rollBack();
            self::$error = $e -> getMessage();
            return false;
        }
    }

    public static function cancelAllPayOrder()
    {
        $time = Carbon::now() -> subMinutes(15) -> toDateTimeString();

        $order = SwtTransferOrderBuyer::with('order') -> where('lock_at','<', $time) -> where('pay_status', 0) -> get();

        if(!$order) {
            return false;
        }

        $order -> map( function($order) {
           $order -> order -> status = 0;
           $order -> order -> buyer_order_id = null;
           $order -> order -> save();
           $order -> pay_status = 3;
           $order -> cancel_desc = '支付超时自动取消';
           $order -> save();
        });

        return true;
    }

    public static function confirmPayOrder(int $id, int $user_id) : bool
    {
        $order = SwtTransferOrder::find($id);

        if($order -> seller_id != $user_id) {
            self::$error = "订单不存在";
            return false;
        }

        $buyer_order = SwtTransferOrderBuyer::where('order_id', $id) -> where('pay_status', 1) -> first();

        if(!$buyer_order) {
            self::$error = "订单不存在";
            return false;
        }

        $seller_trade_info = SwtTradeAddress::whereHas('trade_account', function ($query) {
            $query->where('type', '1');
        })
            -> where('user_id', $order['seller_id'])
            -> first();

        if(!$seller_trade_info) {
            self::$error = "卖家账户不存在";
            return false;
        }

        $buyer_trade_info = SwtTradeAddress::whereHas('trade_account', function ($query) {
            $query->where('type', '1');
        })
            -> where('user_id', $buyer_order['buyer_id'])
            -> first();

        if(!$buyer_trade_info) {
            self::$error = "买家账户不存在";
            return false;
        }

        DB::beginTransaction();

        try {
            $order -> status = 4;

            $res = $order -> save();

            if(!$res) {
                throw new Exception("订单状态修改失败");
            }

            $buyer_order -> pay_status = 2;

            $res = $buyer_order -> save();

            if(!$res) {
                throw new Exception("订单状态修改失败");
            }

            $seller_trade_info -> lock_total -= $order -> real_total;

            $res = $seller_trade_info -> save();

            if(!$res) {
                throw new Exception("卖家金额扣减失败");
            }

            TradeLogLogic::create(
                $address_id = $seller_trade_info -> id,
                $user_id,
                $source_type = 5,
                $text = "转让".$order -> total.'代币，手续费'.$order->fee,
                $change_type = 1,
                $change_amount = $order -> total
            );

            $buyer_trade_info -> total += $order -> total;

            $res = $buyer_trade_info -> save();

            if(!$res) {
                throw new Exception("卖家金额增加失败");
            }

            TradeLogLogic::create(
                $address_id = $buyer_trade_info -> id,
                $user_id,
                $source_type = 5,
                $text = "转让".$order -> total.'代币',
                $change_type = 0,
                $change_amount = $order -> total
            );

            DB::commit();
        } catch (Exception $e)
        {
            DB::rollBack();
            self::$error = $e -> getMessage();
            return false;
        }

        return true;
    }

    public static function cancelPayOrder(int $buyer_order_id, string $cancel_desc) : bool
    {
        $order = SwtTransferOrderBuyer::with('order') -> find($buyer_order_id);

        if(!$order) {
            self::$error = "未找到要取消的订单";
            return false;
        }

        if($order -> status != 0) {
            self::$error = "当前状态已无法取消";
            return false;
        }

        $order -> order -> status = 0;

        $order -> order -> buyer_order_id = null;

        $order -> pay_status = 3;

        $order -> cancel_desc = $cancel_desc;

        $res = $order -> order -> save();

        if(!$res) {
            self::$error = "取消订单失败";
            return false;
        }

        $res = $order -> save();

        if(!$res) {
            self::$error = "取消订单失败";
            return false;
        }

        return true;
    }

    public static function getBuyerOrderList(int $user_id, string $pay_status, int $pageSize, int $pageNo) : array
    {
        $where = [
            ['buyer_id','=',$user_id]
        ];

        if($pay_status !== "") {
            $where[] = ['pay_status', '=', $pay_status];
        }

        $orders = SwtTransferOrderBuyer::with('order') -> where($where) -> orderBy('id','desc');

        $pages = $orders -> paginate(
            perPage: $pageSize,
            columns: ['*'],
            pageName: 'pageNo',
            page: $pageNo
        );

        $list = $orders -> get() -> toArray();

        foreach($list as &$v)
        {
            $v = array_merge($v['order'], $v);
        }

        return [
            'list'        => $list,
            'pageNo'      => $pages->currentPage(),
            'pageSize'    => $pages->perPage(),
            'count'       => $pages->total(),
            'noMore'      => !$pages->hasMorePages(),
        ];
    }

    public static function getSellerOrderList(int $user_id, string $sign_status, string $status, int $pageSize, int $pageNo) : array
    {
        $where = [
            ['seller_id','=',$user_id]
        ];

        if($sign_status !== "") {
            $where[] = ['sign_status', '=', $sign_status];
            if($sign_status == 0) {
                $where[] = ['status','=', 0];
            }
        }

        if($status !== "") {
            $where[] = ['status', '=', $status];
        }

        $orders = SwtTransferOrder::with('seller') -> where($where) -> orderBy('id','desc');

        $pages = $orders -> paginate(
            perPage: $pageSize,
            columns: ['*'],
            pageName: 'pageNo',
            page: $pageNo
        );

        $list = $orders -> get();

        return [
            'list'        => $list,
            'pageNo'      => $pages->currentPage(),
            'pageSize'    => $pages->perPage(),
            'count'       => $pages->total(),
            'noMore'      => !$pages->hasMorePages(),
        ];
    }
}
